﻿using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using KZ.Exception;
using KZ.Lottery.Entities;
using KZ.Lottery.Resources;
using KZ.Utilities;
using System;

namespace KZ.Lottery.DAL
{
    public class RuleDetailDAL
    {
        private static RuleDetail CreateRuleDetailFromReader(SqlDataReader reader)
        {
            RuleDetail ruleDetail = new RuleDetail
            {
                RuleDetailID = Utility.StringParse(reader[RuleDetailColumns.RuleDetailID.ToString()]),
                RuleID = Utility.StringParse(reader[RuleDetailColumns.RuleID.ToString()]),
                Line = Utility.IntParse(reader[RuleDetailColumns.Line.ToString()]),
                ResultDate = Utility.DateTimeParse(reader[RuleDetailColumns.ResultDate.ToString()]),
                ChannelID = Utility.StringParse(reader[RuleDetailColumns.ChannelID.ToString()]),
                ChannelName = Utility.StringParse(reader[RuleDetailColumns.ChannelName.ToString()]),
                Head = Utility.StringParse(reader[RuleDetailColumns.Head.ToString()]),
                Tail = Utility.StringParse(reader[RuleDetailColumns.Tail.ToString()]),
                HeadCapital = Utility.DecimalParse(reader[RuleDetailColumns.HeadCapital.ToString()]),
                TailCapital = Utility.DecimalParse(reader[RuleDetailColumns.TailCapital.ToString()]),
                HeadActualCapital = Utility.DecimalParse(reader[RuleDetailColumns.HeadActualCapital.ToString()]),
                TailActualCapital = Utility.DecimalParse(reader[RuleDetailColumns.TailActualCapital.ToString()]),
                HeadWinAmount = Utility.DecimalParse(reader[RuleDetailColumns.HeadWinAmount.ToString()]),
                TailWinAmount = Utility.DecimalParse(reader[RuleDetailColumns.TailWinAmount.ToString()]),
            };

            return ruleDetail;
        }

        private static RuleDetail CreateRuleDetailFromReaderWithChannel(SqlDataReader reader)
        {
            RuleDetail ruleDetail = new RuleDetail
            {
                RuleDetailID = Utility.StringParse(reader[RuleDetailColumns.RuleDetailID.ToString()]),
                RuleID = Utility.StringParse(reader[RuleDetailColumns.RuleID.ToString()]),
                Line = Utility.IntParse(reader[RuleDetailColumns.Line.ToString()]),
                MondayChannelName = Utility.StringParse(reader[RuleDetailColumns.MondayChannelName.ToString()]),
                TuesdayChannelName = Utility.StringParse(reader[RuleDetailColumns.TuesdayChannelName.ToString()]),
                WednesdayChannelName = Utility.StringParse(reader[RuleDetailColumns.WednesdayChannelName.ToString()]),
                ThursdayChannelName = Utility.StringParse(reader[RuleDetailColumns.ThursdayChannelName.ToString()]),
                FridayChannelName = Utility.StringParse(reader[RuleDetailColumns.FridayChannelName.ToString()]),
                SaturdayChannelName = Utility.StringParse(reader[RuleDetailColumns.SaturdayChannelName.ToString()]),
                SundayChannelName = Utility.StringParse(reader[RuleDetailColumns.SundayChannelName.ToString()]),
            };

            return ruleDetail;
        }

        public static string GetRuleDetailID(string no, string channelID)
        {
            try
            {
                DataAccessHelper.SqlCmd.Parameters.Add("No", SqlDbType.NVarChar).Value = no;
                DataAccessHelper.SqlCmd.Parameters.Add("ChannelID", SqlDbType.NVarChar).Value = channelID;

                string ruleID = Utility.StringParse(DataAccessHelper.ExecuteScalarWithTransaction(CommandType.StoredProcedure, KZ_StoreName.RuleDetailGetID));
                if (ruleID.EndsWith(",")) { ruleID = ruleID.Remove(ruleID.Length - 1); }
                return ruleID;
            }
            catch (SqlException ex)
            {
                Log.LogEx("GetRuleDetailID", ex);
                throw new DataAccessException(KZ_Message.BLM_ERR_RULEDETAIL_GET);
            }
        }

        public static RuleDetail GetRuleDetailByID(string ruleDetailID)
        {
            try
            {
                RuleDetail ruleDetail = new RuleDetail();

                DataAccessHelper.SqlCmd.Parameters.Add("RuleDetailID", SqlDbType.NVarChar).Value = ruleDetailID;
                using (SqlDataReader reader = DataAccessHelper.ExecuteQuery(CommandType.StoredProcedure, KZ_StoreName.RuleDetailGetByID))
                {
                    while (reader.Read())
                    {
                        ruleDetail = CreateRuleDetailFromReader(reader);
                    }
                }

                return ruleDetail;
            }
            catch (SqlException ex)
            {
                Log.LogEx("GetRuleDetailByID", ex);
                throw new DataAccessException(KZ_Message.BLM_ERR_RULEDETAIL_GET);
            }
        }

        public static List<RuleDetail> GetRuleDetailList(string ruleID)
        {
            try
            {
                List<RuleDetail> ruleDetailList = new List<RuleDetail>();

                DataAccessHelper.SqlCmd.Parameters.Add("RuleID", SqlDbType.NVarChar).Value = ruleID;
                using (SqlDataReader reader = DataAccessHelper.ExecuteQuery(CommandType.StoredProcedure, KZ_StoreName.RuleDetailGetList))
                {
                    while (reader.Read())
                    {
                        ruleDetailList.Add(CreateRuleDetailFromReader(reader));
                    }
                }

                foreach (RuleDetail item in ruleDetailList)
                {
                    item.RuleDetailChannelList = RuleDetailChannelDAL.GetRuleDetailChannelList(item.RuleDetailID);
                }

                return ruleDetailList;
            }
            catch (SqlException ex)
            {
                Log.LogEx("GetRuleDetailList", ex);
                throw new DataAccessException(KZ_Message.BLM_ERR_RULEDETAIL_GET);
            }
        }

        public static List<RuleDetail> GetRuleDetailListWithChannel(string ruleID)
        {
            try
            {
                List<RuleDetail> ruleDetailList = new List<RuleDetail>();

                DataAccessHelper.SqlCmd.Parameters.Add("RuleID", SqlDbType.NVarChar).Value = ruleID;
                using (SqlDataReader reader = DataAccessHelper.ExecuteQuery(CommandType.StoredProcedure, KZ_StoreName.RuleDetailListWithChannel))
                {
                    while (reader.Read())
                    {
                        ruleDetailList.Add(CreateRuleDetailFromReaderWithChannel(reader));
                    }
                }

                return ruleDetailList;
            }
            catch (SqlException ex)
            {
                Log.LogEx("GetRuleDetailChannelListWithChannel", ex);
                throw new DataAccessException(KZ_Message.BLM_ERR_RULEDETAIL_GET);
            }
        }

        /// <summary>
        /// Delete but except id
        /// </summary>
        public static bool DeleteRuleDetail(string ruleID, string ruleDetailID)
        {
            try
            {
                DataAccessHelper.SqlCmd.Parameters.Add("RuleID", SqlDbType.NVarChar).Value = ruleID;
                DataAccessHelper.SqlCmd.Parameters.Add("RuleDetailID", SqlDbType.NVarChar).Value = ruleDetailID;
                if (DataAccessHelper.ExecuteNonQueryWithTransaction(CommandType.StoredProcedure, KZ_StoreName.RuleDetailDelete) > 0)
                {
                    return true;
                }

                throw new DataAccessException(KZ_Message.BLM_ERR_RULEDETAIL_DELETE);
            }
            catch (SqlException ex)
            {
                Log.LogEx("DeleteRuleDetail", ex);
                throw new DataAccessException(KZ_Message.BLM_ERR_RULEDETAIL_DELETE);
            }
        }

        public static bool UpdateRuleDetailAmount(string ruleDetailID, DateTime resultDate, string channelID, string head, string tail,
            decimal headWinAmount, decimal tailWinAmount, decimal headCapital, decimal tailCapital, decimal headActualCapital, decimal tailActualCapital)
        {
            try
            {
                DataAccessHelper.SqlCmd.Parameters.Add("RuleDetailID", SqlDbType.VarChar).Value = ruleDetailID;
                DataAccessHelper.SqlCmd.Parameters.Add("ResultDate", SqlDbType.DateTime).Value = resultDate;
                DataAccessHelper.SqlCmd.Parameters.Add("ChannelID", SqlDbType.VarChar).Value = channelID;
                DataAccessHelper.SqlCmd.Parameters.Add("Head", SqlDbType.VarChar).Value = head;
                DataAccessHelper.SqlCmd.Parameters.Add("Tail", SqlDbType.VarChar).Value = tail;
                DataAccessHelper.SqlCmd.Parameters.Add("HeadWinAmount", SqlDbType.Decimal).Value = headWinAmount;
                DataAccessHelper.SqlCmd.Parameters.Add("TailWinAmount", SqlDbType.Decimal).Value = tailWinAmount;
                DataAccessHelper.SqlCmd.Parameters.Add("HeadCapital", SqlDbType.Decimal).Value = headCapital;
                DataAccessHelper.SqlCmd.Parameters.Add("TailCapital", SqlDbType.Decimal).Value = tailCapital;
                DataAccessHelper.SqlCmd.Parameters.Add("HeadActualCapital", SqlDbType.Decimal).Value = headActualCapital;
                DataAccessHelper.SqlCmd.Parameters.Add("TailActualCapital", SqlDbType.Decimal).Value = tailActualCapital;
                
                if (DataAccessHelper.ExecuteNonQueryWithTransaction(CommandType.StoredProcedure, KZ_StoreName.RuleDetailUpdateAmount) > 0)
                {
                    return true;
                }

                throw new DataAccessException(KZ_Message.BLM_ERR_RULE_UPDATE);
            }
            catch (SqlException ex)
            {
                Log.LogEx("UpdateRuleDetailAmount", ex);
                throw new DataAccessException(KZ_Message.BLM_ERR_RULEDETAIL_UPDATE);
            }
        }

        public bool InsertRuleDetail(RuleDetail ruleDetail)
        {
            try
            {
                DataAccessHelper.SqlCmd.Parameters.Add("RuleDetailID", SqlDbType.NVarChar).Value = ruleDetail.RuleDetailID;
                DataAccessHelper.SqlCmd.Parameters.Add("RuleID", SqlDbType.NVarChar).Value = ruleDetail.RuleID;
                DataAccessHelper.SqlCmd.Parameters.Add("Line", SqlDbType.Int).Value = ruleDetail.Line;
                if (DataAccessHelper.ExecuteNonQueryWithTransaction(CommandType.StoredProcedure, KZ_StoreName.RuleDetailInsert) > 0)
                {
                    return true;
                }

                throw new DataAccessException(KZ_Message.BLM_ERR_RULEDETAIL_INSERT);
            }
            catch (SqlException ex)
            {
                Log.LogEx("InsertRuleDetail", ex);
                throw new DataAccessException(KZ_Message.BLM_ERR_RULEDETAIL_INSERT);
            }
        }

        public bool UpdateRuleDetail(RuleDetail ruleDetail)
        {
            try
            {
                DataAccessHelper.SqlCmd.Parameters.Add("RuleDetailID", SqlDbType.NVarChar).Value = ruleDetail.RuleDetailID;
                DataAccessHelper.SqlCmd.Parameters.Add("Line", SqlDbType.Int).Value = ruleDetail.Line;
                if (DataAccessHelper.ExecuteNonQueryWithTransaction(CommandType.StoredProcedure, KZ_StoreName.RuleDetailUpdate) > 0)
                {
                    return true;
                }

                throw new DataAccessException(KZ_Message.BLM_ERR_RULEDETAIL_UPDATE);
            }
            catch (SqlException ex)
            {
                Log.LogEx("UpdateRuleDetail", ex);
                throw new DataAccessException(KZ_Message.BLM_ERR_RULEDETAIL_UPDATE);
            }
        }
    }
}